#include "Thread.h"
#include <event.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>

using namespace std;

namespace PFS
{
    Thread::Thread(thread_fun func)
        :fun(func)
    {
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    }

    Thread::~Thread()
    {
        pthread_attr_destroy(&attr);
        pthread_detach(pthread_self());
    }

    int Thread::start()
    {
        return pthread_create(&thread_id, &attr, fun, this);
    }

    pthread_t Thread::get_id()
    {
        return thread_id;
    }

    int Thread::join()
    {
        return pthread_join(thread_id, NULL);
    }

    int Thread::detach()
    {
        return pthread_detach(thread_id);
    }

    int Thread::exit()
    {
        return pthread_exit(NULL);
    }

    EventThread::EventThread(thread_fun _thread_fun)
        :Thread(_thread_fun)
    {
        base = event_init();
        m_queue = new MsgQueue(base);
    }
    EventThread::~EventThread()
    {
        if(m_queue)
            delete m_queue;
        event_base_loopexit(base, NULL);
    }

    void* EventThread::event_thread_start(void* arg)
    {
        EventThread *thread = (EventThread *)arg;
        event_base_loop(arg->base, 0);
    }
    void EventThread::run()
    {
        int ret = start();    
    }

    void EventThread::set_task(Job* job,void* data)
    {
        struct event_arg *arg = calloc(1, sizeof(struct event_arg));//should be free in the job->run
        arg->job = job;
        arg->data = data;
        arg->data->set_thread(this);
        m_queue.push(arg);//we need the thread pointer to get event_base 
    }

    struct event_base* EventThread::get_event_base()
    {
        return base;
    }

}
